//
// Created by twetec on 25-7-18.
//

#ifndef NETWORK_PROBER_RPC_PERCEPTION_RPC_CALLER_SUSTAIN_PROBE_TARGET_H
#define NETWORK_PROBER_RPC_PERCEPTION_RPC_CALLER_SUSTAIN_PROBE_TARGET_H

#include "perception_rpc_client.pb.h"
#include "perception_rpc_client.grpc.pb.h"

#include "perception_rpc_caller.h"

namespace network_prober::database
{
class ProbeTaskResultModel;
}

namespace network_prober::rpc
{
/**
 * 一个reactor只能针对一个rpc方法
 */
class SustainProbeTargetRPCClientReactor final : public grpc::ClientWriteReactor<network_perception::rpc::SustainProbeTargetRequest>
{
public:
    network_perception::rpc::SustainProbeTargetRequest probeTargetResult{};
    google::protobuf::Empty probeTargetResponse{};

public:
    SustainProbeTargetRPCClientReactor(network_perception::rpc::NetworkPerceptionServer::Stub* RPCClientStubPtr);

    /**
     * 开始调用
     */
    void startCalling();

    /**
     * 等待连接结束
     */
    grpc::Status awaitCallingDone();

private:
    /**
     * 当一次写入完成时调用
     * @param ok 写入是否成功执行
     */
    void OnWriteDone(bool ok) override;

    /**
     * 响应RPC完成。我们将在 OnDone() 中执行最终清理
     */
    void OnDone(const grpc::Status& status) override;

private:
    std::mutex m_mutex;
    std::condition_variable m_condition;
    bool m_callingDone{false};
    grpc::Status m_callingStatus;
    grpc::ClientContext m_clientContext{};
};

class PerceptionRPCCallerSustainProbeTarget final : public PerceptionRPCCaller<PerceptionRPCCallerSustainProbeTarget>
{
public:
    /**
     * 报告目标观测结果
     */
    void reportProbeTaskResults(std::span<database::ProbeTaskResultModel> probeTaskResults);

    /**
     * 调用实现
     */
    void callImpl();
    PerceptionRPCCallerSustainProbeTarget();

private:
    std::unique_ptr<network_perception::rpc::NetworkPerceptionServer::Stub> m_RPCClientStubPtr;
    std::unique_ptr<SustainProbeTargetRPCClientReactor> m_RPCClientReactorPtr;
};

}


#endif //NETWORK_PROBER_RPC_PERCEPTION_RPC_CALLER_SUSTAIN_PROBE_TARGET_H
